# ========================================================== # Outlook Plugin Manager # ========================================================== # Use Case : # Enable or disable Outlook COM Add-ins # for: # 1. Machine-wide Add-ins (HKLM) # 2. User-wide Add-ins (HKU\) # ========================================================== param( [Parameter(Mandatory = $true)] [string[]]$AddinNames, [Parameter(Mandatory = $true)] [string]$Status, [string[]]$ExcludedUsers ) Write-Host "=============================================" Write-Host " Outlook Plugin Manager Started" Write-Host "=============================================" # ---------------------------------------------------------- # Validate Parameters # ---------------------------------------------------------- if (-not $AddinNames -or $AddinNames.Count -eq 0) { Write-Host "[ERROR] Add-in name list is missing." exit 1 } if ([string]::IsNullOrWhiteSpace($Status)) { Write-Host "[ERROR] Status is missing." Write-Host "[INFO] Use Enable or Disable" exit 1 } # ---------------------------------------------------------- # Validate Status # ---------------------------------------------------------- $Status = $Status.Trim().ToLower() if ($Status -notin @("enable","disable")) { Write-Host "[ERROR] Invalid Status : $Status" Write-Host "[INFO] Use Enable or Disable only" exit 1 } # ---------------------------------------------------------- # Excluded System SIDs # ---------------------------------------------------------- $ExcludedSIDs = @( "S-1-5-18", "S-1-5-19", "S-1-5-20" ) # ---------------------------------------------------------- # Convert Excluded Users to SID # ---------------------------------------------------------- foreach ($user in $ExcludedUsers) { try { $sid = ( New-Object System.Security.Principal.NTAccount($user) ).Translate( [System.Security.Principal.SecurityIdentifier] ).Value $ExcludedSIDs += $sid Write-Host "[INFO] Excluding User : $user" } catch { Write-Host "[WARNING] Failed to get SID for user : $user" } } # ---------------------------------------------------------- # Get User SID Registry Keys # ---------------------------------------------------------- $UserSIDs = Get-ChildItem "Registry::HKEY_USERS" | Where-Object { $_.Name -notmatch "_Classes$" -and $_.PSChildName -notin $ExcludedSIDs -and $_.PSChildName -notmatch "^S-1-5-80-" } # ---------------------------------------------------------- # Close Outlook # ---------------------------------------------------------- Write-Host "Closing Outlook..." Get-Process OUTLOOK -ErrorAction SilentlyContinue | ForEach-Object { $_.CloseMainWindow() | Out-Null if (!$_.WaitForExit(10000)) { Write-Host "Force closing Outlook..." $_ | Stop-Process -Force } } # ---------------------------------------------------------- # Function : Set LoadBehavior # ---------------------------------------------------------- function Set-AddinStatus { param( [string]$RegistryPath, [string]$AddinName ) if (Test-Path $RegistryPath) { try { switch ($Status) { "enable" { Set-ItemProperty ` -Path $RegistryPath ` -Name "LoadBehavior" ` -Value 3 ` -ErrorAction Stop Write-Host "[SUCCESS] Enabled Add-in" } "disable" { Set-ItemProperty ` -Path $RegistryPath ` -Name "LoadBehavior" ` -Value 0 ` -ErrorAction Stop Write-Host "[SUCCESS] Disabled Add-in" } } $CurrentValue = ( Get-ItemProperty -Path $RegistryPath ).LoadBehavior Write-Host "[INFO] Add-in Name : $AddinName" Write-Host "[INFO] Registry Path : $RegistryPath" Write-Host "[INFO] Current LoadBehavior : $CurrentValue" return $true } catch { Write-Host "[ERROR] Failed to update add-in" Write-Host $_.Exception.Message } } return $false } # ---------------------------------------------------------- # Process Add-ins # ---------------------------------------------------------- foreach ($AddinName in $AddinNames) { Write-Host "" Write-Host "=================================================" Write-Host "Checking Add-in : $AddinName" Write-Host "=================================================" # ----------------------------------------------------- # Machine-wide Add-ins (HKLM) # ------------------------------------------------------ if ($AddinName -notmatch '^[A-Za-z][A-Za-z0-9]*(\.[A-Za-z0-9]+)+$') { Write-Host "[ERROR] Invalid add-in name: $AddinName" exit 1 } $MachinePaths = @( "HKLM:\Software\Microsoft\Office\Outlook\Addins\$AddinName", "HKLM:\Software\WOW6432Node\Microsoft\Office\Outlook\Addins\$AddinName" ) $MachineWideFound = $false foreach ($Path in $MachinePaths) { if (Test-Path $Path) { $MachineWideFound = $true Write-Host "Machine-wide Add-in Found" $Result = Set-AddinStatus ` -RegistryPath $Path ` -AddinName $AddinName } } # ------------------------------------------------------ # User-wide Add-ins (HKU) # ------------------------------------------------------ if (-not $MachineWideFound) { Write-Host "Machine-wide Add-in Not Found" Write-Host "Checking User-wide Add-ins..." foreach ($sid in $UserSIDs) { Write-Host "" Write-Host "Processing SID : $($sid.PSChildName)" $UserPaths = @( "Registry::HKEY_USERS\$($sid.PSChildName)\Software\Microsoft\Office\Outlook\Addins\$AddinName", "Registry::HKEY_USERS\$($sid.PSChildName)\Software\WOW6432Node\Microsoft\Office\Outlook\Addins\$AddinName" ) foreach ($Path in $UserPaths) { $Result = Set-AddinStatus ` -RegistryPath $Path ` -AddinName $AddinName } } } } Start-Sleep -Seconds 2 # ---------------------------------------------------------- # Restart Outlook # ---------------------------------------------------------- Write-Host "`n[INFO] Restarting Outlook..." try { $OutlookExe = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\OUTLOOK.EXE" -ErrorAction stop)."(default)" if ($OutlookExe -and (Test-Path $OutlookExe)) { Start-Process $OutlookExe } } catch { Write-Host "[WARNING] Could not automatically start Outlook." Write-Host $_.Exception.Message } Write-Host "" Write-Host "=============================================" Write-Host " Outlook Plugin Manager Completed" Write-Host "============================================="